package jbitarrays.api;

import javax.annotation.concurrent.NotThreadSafe;

/**
 * A decorator of {@link InfiniteBitArray} that keeps track of its position in
 * the array. It can only be used for one pass through the array (i.e. it can't
 * be reset), but can be {@link #clone()}ed to give a new {@link CrawlerWriter}
 * at the same location in the {@link InfiniteBitArray}.
 * 
 * @see CrawlerReader the counterpart for reading from an
 *      {@link InfiniteBitArray}
 * @since 1.0
 */
@NotThreadSafe public interface CrawlerWriter {
	/**
	 * Write a single bit and advance this {@link CrawlerWriter}'s index into
	 * its {@link InfiniteBitArray}. <b>Note that implementations may corrupt
	 * data after the indices that are set</b>, especially if there is not a
	 * one-to-one mapping between bits set on the {@link CrawlerWriter} & bits
	 * set on the {@link InfiniteBitArray} - so check the implementation's
	 * documentation.
	 * 
	 * 
	 * @see InfiniteBitArray#set(int, boolean)
	 * @since 1.0
	 */
	public void setNext(boolean value);

	/**
	 * A helper method for more efficient bulk operations - the implementation
	 * may call {@link InfiniteBitArray#setN(int, int, int)}. <b>Note that
	 * implementations may corrupt data after the index or indices that are
	 * set</b>, especially if there is not a one-to-one mapping between bits set
	 * on the {@link CrawlerWriter} & bits set on the {@link InfiniteBitArray} -
	 * so check the implementation's documentation.
	 * 
	 * @throws IllegalArgumentException
	 *             if {@code howMany < 0} or {@code howMany > Integer#SIZE}
	 * @see InfiniteBitArray#setN(int, int, int)
	 * @since 1.0
	 */
	public void setNextN(int howMany, int value) throws IllegalArgumentException;

	/**
	 * Create a new {@link CrawlerWriter} at the same position as this
	 * {@link CrawlerWriter}.
	 * 
	 * @return a new instance of {@link CrawlerWriter} at the same index into
	 *         the {@link InfiniteBitArray} as this {@link CrawlerWriter} is.
	 *         Writing to this {@link CrawlerWriter} <b>may</b> affect the
	 *         returned {@link CrawlerWriter}, and vice versa - so check the
	 *         documentation of the implementation, especially if there is not a
	 *         one-to-one mapping between bits set on the {@link CrawlerWriter}
	 *         & bits set on the {@link InfiniteBitArray}.
	 * @since 1.0
	 */
	public CrawlerWriter clone();

	/**
	 * Start reading from the position this {@link CrawlerWriter} is at
	 * 
	 * @throws UnsupportedOperationException
	 *             this operation is optional
	 * @since 1.0
	 */
	public CrawlerReader toReader() throws UnsupportedOperationException;
}